from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
import json
from config.enums import RedisInitKeyConfig
from exceptions.exception import ServiceException
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_purchase.dao.price_dao import PriceDao
from module_purchase.entity.vo.price_vo import DeletePriceModel, PriceModel, PricePageQueryModel, PriceAddModel
from utils.common_util import CamelCaseUtil
from utils.excel_util import ExcelUtil
from module_plant.service.planter_service import PlanterService
from fastapi import Request


class PriceService:
    """
    每日采购价记录模块服务层
    """

    @classmethod
    async def get_price_list_services(
        cls, query_db: AsyncSession, query_object: PricePageQueryModel, is_page: bool = False
    ):
        """
        获取每日采购价记录列表信息service

        :param query_db: orm对象
        :param query_object: 查询参数对象
        :param is_page: 是否开启分页
        :return: 每日采购价记录列表信息对象
        """
        price_list_result = await PriceDao.get_price_list(query_db, query_object, is_page)

        return price_list_result


    @classmethod
    async def add_price_services(cls, req: Request, query_db: AsyncSession, price_object: PriceAddModel):
        """
        新增每日采购价记录信息service
        :param req: Request对象
        :param query_db: orm对象
        :param price_object: 新增每日采购价记录对象
        :return: 新增每日采购价记录校验结果
        """
        try:
            price_item_list = []
            product_size_str = ",".join(price_object.product_size)
            for planter_id in price_object.planter_id:
                planter_item = await PlanterService.planter_detail_services(query_db, planter_id)
                planter_name = planter_item.planter_name
                area_list = await req.app.state.redis.get(f'{RedisInitKeyConfig.SYS_DICT.key}:product_area')
                filtered_area = filter(lambda unit: unit.get('dictValue') == str(price_object.product_area_id),
                                       json.loads(area_list))
                product_area_name = [d['dictLabel'] for d in filtered_area]
                price_item = PriceModel()
                price_item.year = price_object.year
                price_item.create_by = price_object.create_by
                price_item.create_time = price_object.create_time
                price_item.price = price_object.price
                price_item.purchase_date = price_object.purchase_date
                price_item.update_time = price_object.update_time
                price_item.update_by = price_object.update_by
                price_item.product_size = product_size_str
                price_item.planter_name = planter_name
                price_item.planter_id = planter_id
                price_item.product_area_id = price_object.product_area_id
                price_item.product_area = product_area_name[0]
                price_item.effective_time = price_object.effective_time
                price_item.expiration_time = price_object.expiration_time
                price_item.memo = price_object.memo
                price_item_list.append(price_item)
            for price_item_object in price_item_list:
                await PriceDao.add_price_dao(query_db, price_item_object)
                await query_db.commit()
            return CrudResponseModel(is_success=True, message='新增成功')
        except Exception as e:
            await query_db.rollback()
            raise e

    @classmethod
    async def edit_price_services(cls, query_db: AsyncSession, price_object: PriceModel):
        """
        编辑每日采购价记录信息service
        :param query_db: orm对象
        :param price_object: 编辑每日采购价记录对象
        :return: 编辑每日采购价记录校验结果
        """
        edit_price = price_object.model_dump()
        price_info = await cls.price_detail_services(query_db, price_object.purchase_price_id)
        if price_info.purchase_price_id:
            try:
                planter_item = await PlanterService.planter_detail_services(query_db, edit_price["planter_id"])
                edit_price["planter_name"] = planter_item.planter_name
                await PriceDao.edit_price_dao(query_db, edit_price)
                await query_db.commit()
                return CrudResponseModel(is_success=True, message='更新成功')
            except Exception as e:
                await query_db.rollback()
                raise e
        else:
            raise ServiceException(message='每日采购价记录不存在')

    @classmethod
    async def delete_price_services(cls, query_db: AsyncSession, record_ids: str):
        """
        删除每日采购价记录信息service
        :param query_db: orm对象
        :param record_ids: 删除每日采购价记录对象id
        :return: 删除每日采购价记录校验结果
        """
        if record_ids:
            record_id_list = record_ids.split(',')
            try:
                await PriceDao.delete_price_dao(query_db, record_id_list)
                await query_db.commit()
                return CrudResponseModel(is_success=True, message='删除成功')
            except Exception as e:
                await query_db.rollback()
                raise e
        else:
            raise ServiceException(message='传入记录ID为空')

    @classmethod
    async def price_detail_services(cls, query_db: AsyncSession, record_id: int):
        """
        获取每日采购价记录详细信息service

        :param query_db: orm对象
        :param record_id: 飞书记录ID
        :return: 飞书记录ID对应的信息
        """
        price = await PriceDao.get_price_detail_by_id(query_db, record_id=record_id)
        if price:
            result = PriceModel(**CamelCaseUtil.transform_result(price))
        else:
            result = PriceModel(**dict())

        return result

    @staticmethod
    async def export_price_list_services(price_list: List):
        """
        导出每日采购价记录信息service

        :param price_list: 每日采购价记录信息列表
        :return: 每日采购价记录信息对应excel的二进制数据
        """
        # 创建一个映射字典，将英文键映射到中文键
        mapping_dict = {
            'recordId': '每日收购价格记录Id',
            'year': '数据年份',
            'fabur': '发布人',
            'fabusj': '发布时间',
            'price': '收购单价',
            'recDate': '收购日期',
            'gengxinr': '更新人',
            'gengxinsj': '更新时间',
            'productSize': '产品规格',
            'jiluid': '自动编号',
            'vendorName': '种植主体名称',
            'vendorId': '种植主体id',
            'productAreaId': '产区id',
            'productArea': '产区',
        }
        binary_data = ExcelUtil.export_list2excel(price_list, mapping_dict)

        return binary_data
